import {
  PublicClientApplication,
  InteractionRequiredAuthError
} from '@azure/msal-browser'
import {
  MSAL_CLIENTID,
  MSAL_REDIRECT_URI,
  MSAL_CACHE_LOCATION,
  MSAL_LOGOUT_REDIRECT_URI,
  MSAL_AUTHORITY,
  MICROSOFT_CLIENTID,
  MICROSOFT_REDIRECT_URI
} from '@/components/storybook/settings/msalSetting'
import { merge } from 'lodash'
import router from '@/components/storybook/router'

export const msalConfig = {
  auth: {
    clientId: MSAL_CLIENTID,
    authority: MSAL_AUTHORITY,
    redirectUri: MSAL_REDIRECT_URI,
    postLogoutRedirectUri: MSAL_LOGOUT_REDIRECT_URI,
    navigateToLoginRequestUrl: true
  },
  cache: {
    cacheLocation: MSAL_CACHE_LOCATION,
    storeAuthStateInCookie: false
  }
}

export const loginRequest = { scopes: ['User.Read'] }

export const tokenRequest = {
  scopes: ['User.Read'],
  forceRefresh: false
}

export const msalInstance = new PublicClientApplication(msalConfig)

export function useMsal() {
  const loginPopup = async options => {
    return await msalInstance.loginPopup(merge(loginRequest, options))
  }

  const logoutPopup = async (request = {}) => {
    return await msalInstance.logoutRedirect(
      merge(
        {
          postLogoutRedirectUri: MSAL_LOGOUT_REDIRECT_URI,
          mainWindowRedirectUri: MSAL_LOGOUT_REDIRECT_URI,
          account: getAccount()
        },
        request
      )
    )
  }

  const getAccount = () => {
    const accounts = msalInstance.getAllAccounts()
    return accounts.length ? accounts[0] : {}
  }

  const getTokenRedirect = async request => {
    try {
      return await msalInstance.acquireTokenSilent(request)
    } catch (error) {
      if (error instanceof InteractionRequiredAuthError) {
        return await msalInstance.loginPopup(request)
      } else {
        throw 'silent token acquisition fails. acquiring token using redirect.'
      }
    }
  }

  const getTokenCache = () => {
    return msalInstance.getTokenCache()
  }

  const getUserAuthorization = (...args) => {
    const [
      tenantId,
      userId,
      scope = 'offline_access user.read User.ReadBasic.All User.Read.All Group.Read.All TeamsAppInstallation.ReadForUser',
      subjectCode
    ] = args

    const iWidth = 482
    const iHeight = 660
    const iTop = (window.screen.availHeight - 30 - iHeight) / 2
    const iLeft = (window.screen.availWidth - 10 - iWidth) / 2
    const state = JSON.stringify(
      subjectCode
        ? {
            tenantId: `${tenantId}_${userId}_${subjectCode}`,
            tokenType: 'admin'
          }
        : { tenantId: `${tenantId}_${userId}`, tokenType: 'admin' }
    )

    const { href } = router.resolve({
      name: '/',
      query: {
        client_id: MICROSOFT_CLIENTID,
        response_type: 'code',
        redirect_uri: MICROSOFT_REDIRECT_URI,
        response_mode: 'query',
        prompt: 'select_account',
        scope,
        state
      }
    })
    window.open(
      `https://login.microsoftonline.com/common/oauth2/v2.0/authorize${href}`,
      'MSPbots are to get your permission',
      `resizable,scrollbars=no,status=1,height=${iHeight},innerHeight=${iHeight},width=${iWidth},innerWidth=${iWidth},top=${iTop},left=${iLeft},toolbar=no,menubar=no,location=no,titlebar=no`
    )
  }

  return {
    instance: msalInstance,
    loginPopup,
    logoutPopup,
    getAccount,
    getTokenRedirect,
    getTokenCache,
    getUserAuthorization
  }
}
